package com.yizisu.playerlibrary.view.video_view.view

import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.SeekBar
import androidx.appcompat.R
import androidx.appcompat.widget.AppCompatSeekBar
import androidx.core.view.setMargins
import com.yizisu.playerlibrary.IYzsPlayer
import com.yizisu.playerlibrary.view.video_view.helper.IPlayerConfig
import com.yizisu.playerlibrary.view.video_view.helper.IPlayerHelper
import com.yizisu.playerlibrary.view.video_view.helper.PlayerControllerBarHelper.Companion.DEFAULT_DELAY_DURATION
import com.yizisu.playerlibrary.view.video_view.helper.SeekbarEvent
import com.yizisu.playerlibrary.view.video_view.helper.dip

/**
 * 进度条
 */
open class PlayerSeekBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = R.attr.seekBarStyle
) : AppCompatSeekBar(
    context,
    attrs,
    defStyleAttr
), IPlayerHelper {
    companion object {
        fun newInstance(view: ViewGroup) = PlayerSeekBar(view.context).apply {
            view.addView(this,
                FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT
                ).apply {
                    gravity = Gravity.BOTTOM
                    setMargins(dip(16))
                })
        }
    }

    private var playerConfig: IPlayerConfig? = null
    private var isTouchSeekbar = false
    private val playerControllerData
        get() = playerConfig?.playerControllerBarHelperData?.value

    override fun onAttachPlayerConfig(playerConfig: IPlayerConfig) {
        super.onAttachPlayerConfig(playerConfig)
        this.playerConfig = playerConfig
        setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    updateSeekbarListener(true, progress)
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
                isTouchSeekbar = true
                updateSeekbarListener(true, progress)
                playerControllerData?.show(0)
            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {
                isTouchSeekbar = false
                updateSeekbarListener(false, progress)
                if (seekBar.max > 0) {
                    playerConfig.player?.seekTo(seekBar.progress.toLong())
                }
                playerControllerData?.hide(DEFAULT_DELAY_DURATION)
            }
        })
    }

    override fun onDetachedPlayerConfig(playerConfig: IPlayerConfig) {
        super.onDetachedPlayerConfig(playerConfig)
        this.playerConfig = null
    }

    private fun updateSeekbarListener(isTouch: Boolean, progress: Int) {
        val old = playerConfig?.seekBarEventData?.value
        val new = if (old == null) {
            SeekbarEvent(
                isTouch,
                progress.toLong()
            )
        } else {
            old.isTouch = isTouch
            old.progress = progress.toLong()
            old
        }
        playerConfig?.updateSeekBarEvent(new)
    }

    override fun isNeedPlayerListener(): Boolean {
        return true
    }

    override fun onTick(playerModel: IYzsPlayer.Model) {
        super.onTick(playerModel)
        if (!isTouchSeekbar) {
            this.max = playerModel.totalDuration.toInt()
            this.secondaryProgress = playerModel.currentBufferDuration.toInt()
            this.progress = playerModel.currentDuration.toInt()
        }
    }

    override fun onPlayerModelChange(playerModel: IYzsPlayer.Model) {
        super.onPlayerModelChange(playerModel)
        initSeekbar()
    }

    private fun initSeekbar() {
        this.max = 0
        this.secondaryProgress = 0
        this.progress = 0
    }
}